using AssemblyVerifier;
using DynamicProxies;
using DynamicProxies.Tests.InterfaceImplementation;
using DynamicProxies.Tests.Types;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System;
using System.Reflection;
using System.Reflection.Emit;

namespace DynamicProxies.Tests
{
	[TestClass]
	public sealed class GenericTests : BaseTests, IImplementThis
	{
		[TestMethod]
		public void CreateWithGenericMethods()
		{
			var generic = Proxy.Create<ClassWithGenericMethods>(this);
			Assert.AreEqual(2, generic.ReturnArgument<int>(2));
			Assert.AreEqual("Hello", generic.ReturnArgument<string>("Hello"));
			Assert.AreEqual(this, generic.ReturnArgumentWithInheritanceConstrains<GenericTests>(this));
			Assert.AreEqual(2, generic.ReturnArgumentInMiddlePosition<int>(3, 2, "Hello"));
			Assert.AreEqual("constraint", generic.ReturnArgumentWithClassConstraint<string>("constraint"));
			Assert.AreEqual(4, 
				generic.ReturnArgumentWithBaseClassConstrains<SimpleDataClass>(new SimpleDataClass(4)).Value);
		}

		[TestMethod]
		public void CreateForGenericClosedTypeWithDefaultContext()
		{
			var simple = Proxy.Create<SimpleGeneric<string, int, Guid>>(this);
			Assert.AreEqual("Hello", simple.ReflectFirstType("Hello"));
			Assert.AreEqual(33, simple.ReflectSecondType(33));
			var newGuid = Guid.NewGuid();
			Assert.AreEqual(newGuid, simple.ReflectThirdType(newGuid));
		}

		[TestMethod]
		public void CreateForGenericClosedType()
		{
			var simple = Proxy.Create<SimpleGeneric<string, int, Guid>>(this);
			Assert.AreEqual("Hello", simple.ReflectFirstType("Hello"));
			Assert.AreEqual(33, simple.ReflectSecondType(33));
			Guid newGuid = Guid.NewGuid();
			Assert.AreEqual(newGuid, simple.ReflectThirdType(newGuid));
		}
	}
}
